package com.pm.buglist.service.impl;


import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pm.buglist.domain.SysFiles;
import com.pm.buglist.mapper.SysFilesMapper;
import com.pm.buglist.service.SysFilesService;
import com.pm.common.config.ParamConfig;
import com.pm.common.core.domain.AjaxResult;
import com.pm.common.core.domain.model.LoginUser;
import com.pm.common.enums.FileType;
import com.pm.common.exception.ServiceException;
import com.pm.common.utils.DateUtils;
import com.pm.common.utils.DownFileUtils;
import com.pm.common.utils.PlmSoapUtil;
import com.pm.common.utils.SecurityUtils;
import com.pm.common.utils.file.FileUploadUtils;
import com.pm.project.mapper.ProjectListNodeMemberMapper;
import com.pm.system.service.ISysConfigService;
import com.github.yitter.idgen.YitIdHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.net.ssl.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.KeyManagementException;
import java.security.cert.X509Certificate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 系统文件表 服务实现类
 * </p>
 *
 * @author wwm
 * @since 2023-12-14
 */
@Service
@Slf4j
public class SysFilesServiceImpl extends ServiceImpl<SysFilesMapper, SysFiles> implements SysFilesService {
    @Resource
    private SysFilesMapper sysFileMapper;

    @Resource
    private ParamConfig paramConfig;

    @Resource
    private ISysConfigService _sysConfigService;

    @Resource
    ProjectListNodeMemberMapper projectListNodeMemberMapper;


    /**
     * 通过配置项下载文件
     * @param configKey
     * @param response
     * @return
     */
    @Override
    public void  getFileByConfig(String configKey, HttpServletResponse response){
        String value= _sysConfigService.selectConfigByKey(configKey);
        if(!value.isEmpty()){
            long fileId = Long.parseLong(value);
            downloadFile(fileId,response);
        }else {
            throw  new ServiceException("文件模板没有配置！请联系系统管理员");
        }
    }

    /**
     * 通用文件上传接口
     * @param file
     * @return
     */
    @Override
    public AjaxResult fileUploadOther(MultipartFile file) {
        return FileUpload(file,FileType.OTHERS.getCode(),null);
    }

    @Override
    public List<SysFiles> queryFileList(JSONObject param) {
        return sysFileMapper.queryFileList(param);
    }

//    @Override
//    public void downloadPLMFile(Long id, HttpServletResponse response) {
//
//        try{
//            String fileId = projectListNodeMemberMapper.queryPLMFileId(id);
//            String url = getFileUrlById(fileId);
//            String path = paramConfig.getFilePath()+File.separator+"PLM"+ File.separator+DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,new Date()) +File.separator+ UUID.randomUUID()+".zip";
//            DownFileUtils.downloadPLMFile(url,path,response);
//        }catch (Exception e){
//            e.printStackTrace();
//            log.error("下载PLM文件异常:{}",e.getMessage());
//        }
//
//    }

//    private String getFileUrlById(String fileId) throws Exception {
//
//            String plmAddr =paramConfig.getPlmAddr();
//            HashMap<String, String> paramMap = new HashMap<>();
//            paramMap.put("docId", fileId);
//            log.info("查询PLM请求参数:{}",paramMap);
//
//            // 创建一个信任所有证书的信任管理器
//            TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
//                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
//                    return new X509Certificate[0];
//                }
//                public void checkClientTrusted(X509Certificate[] certs, String authType) {
//                }
//                public void checkServerTrusted(X509Certificate[] certs, String authType) {
//                }
//            } };
//
//            // 禁用SSL证书验证
//            SSLContext sc = SSLContext.getInstance("SSL");
//            sc.init(null, trustAllCerts, new java.security.SecureRandom());
//            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
//
//            // 创建一个忽略主机名验证的HostnameVerifier
//            HostnameVerifier allHostsValid = new HostnameVerifier() {
//                public boolean verify(String hostname, SSLSession session) {
//                    return true;
//                }
//            };
//            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
//
//            String res = (String)  PlmSoapUtil.getWebServiceAndSoap(plmAddr,"DownloadFile_PM",paramMap,null);
//            log.info("返回数据:{}",res);
//            JSONObject obj = JSONObject.parseObject(res);
//            if(obj.getIntValue("code")==200){
//                return  obj.getString("data");
//            }
//            return null;
//
//    }

    /**
     * 批量上传文件
     * @param files
     * @param type
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public List<SysFiles> BatchFileUpLoad(MultipartFile[] files, String type, String remark) {
        //获取登录用户信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        //存储上传成功并且记录数据库的sysFile对象
        List<SysFiles> filesList=new ArrayList<>();
        //存储上传不成功的文件名称
        List<String> list=new ArrayList<>();
        for (MultipartFile file : files) {
            if(type==null||type.isEmpty()){//文件类型为空默认其他文件
                type=FileType.OTHERS.getCode();
            }
            String oriFileName = file.getOriginalFilename();//原文件名
//                if(!oriFileName.contains("-")){
//                    throw new RuntimeException(oriFileName+"该文件命名不规范，请认真查看批量报价导入模板中的使用说明，正确填写文件名称！");
//                }
            String url ="";
            if(type.equals(FileType.AVATAR.getCode())){//头像文件
            }else{
                try {
                    url = FileUploadUtils.uploadFile(paramConfig.getFilePath(),file,type);
                }catch (Exception e){
                    e.printStackTrace();
                    log.error("批量上传文件异常"+e);
                }
            }

            //判断文件是否上传成功
            if(!StringUtils.isEmpty(url)){
                String suffix=oriFileName.substring(oriFileName.lastIndexOf("."));//文件后缀
                String newFileName=url.substring(url.lastIndexOf(File.separator)+1);
                //文件大小
                double sizeKb=Math.round((file.getSize()/1024.0) * 100) / 100.0;

                //上传成功记录数据表
                SysFiles sysFiles = new SysFiles();
                long id = YitIdHelper.nextId();
                sysFiles.setId(id);
                sysFiles.setOriginName(oriFileName);
                sysFiles.setPhysicsName(newFileName);
                sysFiles.setSuffix(suffix);
                sysFiles.setPath(url);
                sysFiles.setType(type);
                sysFiles.setCreateBy(userId);
                sysFiles.setCreateTime(LocalDateTime.now());
                sysFiles.setSizeKb(sizeKb);
                sysFiles.setRemark(remark);
                sysFileMapper.insert(sysFiles);
                sysFiles.setFid(id+"");
                filesList.add(sysFiles);
            }else {
                list.add(oriFileName);
            }
        }
        if(CollectionUtils.isEmpty(list)){
            return filesList;
        }else {
            throw new RuntimeException(list.toString()+"这些文件上传失败了，请重新上传这些上传失败的文件");
        }
    }

    /**
     * 文件上传
     * @param file
     * @param type
     * @return 返回SysFiles对象
     */
    @Override
    public AjaxResult FileUpload(MultipartFile file, String type, String remarks) {
        try {
            //获取登录用户信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            if(type==null||type.isEmpty()){//文件类型为空默认其他文件
                type=FileType.OTHERS.getCode();
            }
            String url ="";
            if(type.equals(FileType.AVATAR.getCode())){//头像文件
            }else{
                url = FileUploadUtils.uploadFile(paramConfig.getFilePath(),file,type);
            }
            //判断文件是否上传成功
            if(!StringUtils.isEmpty(url)){
                String oriFileName = file.getOriginalFilename();//原文件名
                String suffix=oriFileName.substring(oriFileName.lastIndexOf("."));//文件后缀
                String newFileName=url.substring(url.lastIndexOf(File.separator)+1);
                //文件大小
                double sizeKb=Math.round((file.getSize()/1024.0) * 100) / 100.0;

                //上传成功记录数据表
                SysFiles sysFiles = new SysFiles();
                long id = YitIdHelper.nextId();
                sysFiles.setId(id);
                sysFiles.setOriginName(oriFileName);
                sysFiles.setPhysicsName(newFileName);
                sysFiles.setSuffix(suffix);
                sysFiles.setPath(url);
                sysFiles.setType(type);
                sysFiles.setCreateBy(userId);
                sysFiles.setCreateTime(LocalDateTime.now());
                sysFiles.setSizeKb(sizeKb);
                sysFiles.setRemark(remarks);
                sysFileMapper.insert(sysFiles);
                sysFiles.setFid(id+"");
                return AjaxResult.success(sysFiles);
            }else {
                return AjaxResult.error("文件上传失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传文件异常:"+e);
            return AjaxResult.error("上传文件异常");
        }
    }

    /**
     * 传入登录用户id的文件上传接口
     * @param file
     * @param type
     * @param userId
     * @param code
     * @return 返回SysFiles对象
     */
    @Override
    public AjaxResult FileUploadTwo(MultipartFile file,String type,Long userId,String code) {
        try {
            if(type==null||type.isEmpty()){//文件类型为空默认其他文件
                type=FileType.OTHERS.getCode();
            }
            String url ="";
            if(type.equals(FileType.AVATAR.getCode())){//头像文件
            }else{
                url = FileUploadUtils.uploadFile(paramConfig.getFilePath(),file,type);
            }
            //判断文件是否上传成功
            if(!StringUtils.isEmpty(url)){
                String oriFileName = file.getOriginalFilename();//原文件名
                String suffix=oriFileName.substring(oriFileName.lastIndexOf("."));//文件后缀
                String newFileName=url.substring(url.lastIndexOf(File.separator)+1);
                //文件大小
                double sizeKb=Math.round((file.getSize()/1024.0) * 100) / 100.0;

                //上传成功记录数据表
                SysFiles sysFiles = new SysFiles();
                long id = YitIdHelper.nextId();
                sysFiles.setId(id);
                sysFiles.setOriginName(oriFileName);
                sysFiles.setPhysicsName(newFileName);
                sysFiles.setSuffix(suffix);
                sysFiles.setPath(url);
                sysFiles.setType(type);
                sysFiles.setCreateBy(userId);
                sysFiles.setCreateTime(LocalDateTime.now());
                sysFiles.setSizeKb(sizeKb);
                if(StringUtils.isEmpty(code)){
                    if(oriFileName.length()>15){
                        String substring = oriFileName.substring(0, 15);
                        sysFiles.setRemark(substring);
                    }
                }else {
                    sysFiles.setRemark(code);
                }
                sysFileMapper.insert(sysFiles);
                sysFiles.setFid(id+"");
                return AjaxResult.success(sysFiles);
            }else {
                return AjaxResult.error("文件上传失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传文件异常:"+e);
            return AjaxResult.error("上传文件异常");
        }
    }

    /**
     * 上传文件，返回文件id
     * @param file  文件
     * @param type  文件类型
     * @return
     */
    @Override
    public Long FileUploadId(MultipartFile file,String type) throws IOException {

        //获取登录用户信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        if(type==null||type.isEmpty()){//文件类型为空默认其他文件
            type=FileType.OTHERS.getCode();
        }
        String url ="";
        try {
            url = FileUploadUtils.uploadFile(paramConfig.getFilePath(), file, type);

            //判断文件是否上传成功
            if(!StringUtils.isEmpty(url)) {
                String oriFileName = file.getOriginalFilename();//原文件名
                String suffix = oriFileName.substring(oriFileName.lastIndexOf("."));//文件后缀
                String newFileName = url.substring(url.lastIndexOf(File.separator) + 1);
                //文件大小
                double sizeKb = Math.round((file.getSize() / 1024.0) * 100) / 100.0;

                //上传成功记录数据表
                SysFiles sysFiles = new SysFiles();
                long id = YitIdHelper.nextId();
                sysFiles.setId(id);
                sysFiles.setOriginName(oriFileName);
                sysFiles.setPhysicsName(newFileName);
                sysFiles.setSuffix(suffix);
                sysFiles.setPath(url);
                sysFiles.setType(type);
                sysFiles.setCreateBy(userId);
                sysFiles.setCreateTime(LocalDateTime.now());
                sysFiles.setSizeKb(sizeKb);
                sysFileMapper.insert(sysFiles);
                sysFiles.setFid(id + "");
                return id;
            }else {
                throw new ServiceException("文件上传异常");
            }
        }catch (Exception ex){
            throw ex;
        }
    }

    /**
     * 不记录上传人id上传文件，返回文件id
     * @param file  文件
     * @param type  文件类型
     * @return
     */
    @Override
    public Long FileUploadIdTwo(MultipartFile file,String type) throws IOException {

        //获取登录用户信息
//        LoginUser loginUser = SecurityUtils.getLoginUser();
//        Long userId = loginUser.getUserId();
        if(type==null||type.isEmpty()){//文件类型为空默认其他文件
            type=FileType.OTHERS.getCode();
        }
        String url ="";
        try {
            url = FileUploadUtils.uploadFile(paramConfig.getFilePath(), file, type);

            //判断文件是否上传成功
            if(!StringUtils.isEmpty(url)) {
                String oriFileName = file.getOriginalFilename();//原文件名
                String suffix = oriFileName.substring(oriFileName.lastIndexOf("."));//文件后缀
                String newFileName = url.substring(url.lastIndexOf(File.separator) + 1);
                //文件大小
                double sizeKb = Math.round((file.getSize() / 1024.0) * 100) / 100.0;

                //上传成功记录数据表
                SysFiles sysFiles = new SysFiles();
                long id = YitIdHelper.nextId();
                sysFiles.setId(id);
                sysFiles.setOriginName(oriFileName);
                sysFiles.setPhysicsName(newFileName);
                sysFiles.setSuffix(suffix);
                sysFiles.setPath(url);
                sysFiles.setType(type);
//                sysFiles.setCreateBy(userId);
                sysFiles.setCreateTime(LocalDateTime.now());
                sysFiles.setSizeKb(sizeKb);
                sysFileMapper.insert(sysFiles);
                sysFiles.setFid(id + "");
                return id;
            }else {
                throw new ServiceException("文件上传异常");
            }
        }catch (Exception ex){
            throw ex;
        }
    }

    @Override
    public AjaxResult delFileById(Long id) {
        //根据id查找对应的文件
        try {
            SysFiles sysFiles = sysFileMapper.selectById(id);
            String path = sysFiles.getPath();
            File file = new File(paramConfig.getFilePath()+File.separator+path);
            boolean delete = FileUploadUtils.delete(file);
            if(delete){
                LoginUser loginUser = SecurityUtils.getLoginUser();
                Long userId = loginUser.getUserId();
                sysFiles.setUpdateBy(userId);
                sysFiles.setUpdateTime(LocalDateTime.now());
                sysFiles.setDelFlag("2");
                sysFileMapper.updateById(sysFiles);
                return AjaxResult.success("删除成功");
            }else {
                return AjaxResult.error("删除失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("删除异常！");
        }

    }

    @Override
    public AjaxResult selectFileById(Long id) {
        try {
            SysFiles sysFiles = sysFileMapper.selectById(id);
            return AjaxResult.success(sysFiles);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("查找异常");
        }
    }

    @Override
    public AjaxResult updateSysFiles(SysFiles sysFiles) {
        try {
            Long id = sysFiles.getId();
            if(ObjectUtils.isEmpty(id)){
                return AjaxResult.error("对应的文件id不能为空");
            }
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            sysFiles.setUpdateBy(userId);
            sysFiles.setUpdateTime(LocalDateTime.now());
            sysFileMapper.updateById(sysFiles);
            return AjaxResult.success("修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("修改异常");
        }
    }

    @Override
    public List<SysFiles> selectFileList(SysFiles sysFiles) {
        return sysFileMapper.selectFileList(sysFiles);
    }


    @Override
    public void downloadFile(Long id,HttpServletResponse response){
        SysFiles sysFiles = sysFileMapper.selectById(id);
        if(ObjectUtils.isEmpty(sysFiles)){
            sysFiles=new SysFiles();
            sysFiles.setPath("");
        }
        File file=new File(paramConfig.getFilePath()+File.separator+sysFiles.getPath());
        byte[] buffer = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            //文件是否存在
            if (file.exists()) {
                //设置响应
                Long size=file.length();
                response.setHeader("Content-Length", size.toString());
                response.setContentType("application/octet-stream;charset=UTF-8");
                response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                response.setHeader("Content-Disposition","attachment;filename="+sysFiles.getFileName());
                response.setCharacterEncoding("UTF-8");
                os = response.getOutputStream();
                bis = new BufferedInputStream(new FileInputStream(file));
                while(bis.read(buffer) != -1){
                    os.write(buffer);
                }
            }else {
                log.error("找不到对应的文件!");
                throw new RuntimeException("找不到对应的文件!");
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(bis != null) {
                    bis.close();
                }
                if(os != null) {
                    os.flush();
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
